<template>
  <div class="chart" :id="cid" />
</template>
<script>
export default {
  data() {
    return {};
  },
  props: {
    // 图表ID
    cid: {
      type: String,
      required: true,
      default: "",
    },
    // 图表数据
    data: {
      type: Array,
      required: true,
      default: () => [],
    },
    // 显示提示框
    tooltip: {
      type: Boolean,
      default: true,
    },
    // 图表位置
    position: {
      type: Array,
      default: () => [["50%", "50%"]],
    },
    // 颜色
    colors: {
      type: Array,
      default: () => ["#157DFA", "#9B4ADC", "#F8A470", "#F928F6", "#3D98D9", "#73D694"],
    },
    // 饼状图半径
    radius: {
      type: [String, Array],
      default: "40%",
    },
    // 饼状图半径宽度
    radiusWidth: {
      type: [Number, String],
      default: 0,
    },
    // 文字
    labels: {
      type: Array,
      default: () => [],
    },
    // 文字颜色
    labelColor: {
      type: String,
      default: "#fff",
    },
    // 文字大小
    labelSize: {
      type: String,
      default: "10px",
    },
    // 文字位置
    labelPos: {
      type: String,
      default: "center",
    },
    // 阴影颜色(默认''则 20%透明)
    shadowColor: {
      type: String,
      default: "",
    },
  },
  watch: {
    data: {
      immediate: true,
      handler() {
        this.$nextTick(() => {
          this.initChart();
        });
      },
    },
  },
  methods: {
    // 初始化图表
    initChart() {
      let domid = document.getElementById(this.cid);
      if (domid?.hasAttribute("_echarts_instance_"))
        domid.removeAttribute("_echarts_instance_");
      let myChart = this.$echarts.init(domid);
      let series = [];
      this.data.forEach((item, index) => {
        let value = eval(item.data) >= 100 ? 100 : item.data;
        let itemObj = {
          type: "pie",
          radius: this.radius,
          hoverAnimation: false,
          name: this.labels[index],
          center: this.position[index],
          data: [value, 100 - value],
          labelLine: { show: false },
          label: {
            show: this.labels.length > 0,
            color: this.labelColor,
            fontSize: this.labelSize,
            position: this.labelPos,
            formatter: (e) => {
              return `${this.labels[index]}\n${Math.round(item.data)}%`;
            },
          },
          itemStyle: {
            normal: {
              color: (colors) => {
                let bg = this.shadowColor;
                if (typeof this.colors[0] === "string") {
                  if (this.shadowColor == "") {
                    bg = this.colors[index] + "33";
                  }
                  let colorList = [this.colors[index], bg];
                  return colorList[colors.dataIndex];
                } else {
                  if (typeof this.colors[0].color === "string") {
                    let num = this.colors.length;
                    for (let i = 0; i < num; i++) {
                      if (value <= this.colors[i].max) {
                        if (this.shadowColor == "") {
                          bg = this.colors[i].color + "33";
                          return [this.colors[i].color, bg][colors.dataIndex];
                        }
                      }
                    }
                  } else {
                    let num = this.colors.length;
                    for (let i = 0; i < num; i++) {
                      if (value <= this.colors[i].max) {
                        if (this.shadowColor == "") {
                          bg = this.colors[i].bgColor;
                          return [this.colors[i].color, bg][colors.dataIndex];
                        }
                      }
                    }
                  }
                }
              },
            },
          },
        };
        series.push(itemObj);
        if (this.radiusWidth) {
          let outObj = {
            type: "pie",
            hoverAnimation: false,
            center: this.position[index],
            radius: [this.radius, this.radius],
            label: { normal: { show: false } },
            data: [
              {
                value: 0,
                itemStyle: {
                  normal: {
                    borderWidth: this.radiusWidth,
                    borderColor: this.colors[index],
                  },
                },
              },
            ],
          };
          series.push(outObj);
        }
      });
      let medias = [];
      this.data.forEach((item, index) => {
        let x = parseInt(this.position[index][0].split("%")[0]);
        let y = this.position[index][1];
        let obj = {
          center: [y, (x > 50 ? x + 5 : x - 5) + "%"],
        };
        medias.push(obj);
        if (this.radiusWidth) {
          medias.push(obj);
        }
      });
      let option = {
        series: series,
        tooltip: {
          show: this.tooltip,
          trigger: "item",
          axisPointer: {
            type: "line",
          },
          formatter: (e) => {
            return `${e.seriesName}: ${e.value}`;
          },
        },
        media: [
          {
            query: { minAspectRatio: 1 },
            option: {
              series: medias,
            },
          },
        ],
      };
      myChart.setOption(option, true, true);
      window.addEventListener("resize", () => {
        myChart.resize();
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.chart {
  width: 100%;
  height: 100%;
}
</style>
